import json
import os

from bs4 import BeautifulSoup
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from django.utils.safestring import mark_safe
from django.views import View

from article.models import Article, UpAndDown, Comment, CategoryTag, CategoryClass, ArticleToTag
from libs.CommonResponse import CommonReponse


# Create your views here.

def article_detail(request, username, pk, *args, **kwargs):
    article_data_obj = Article.objects.filter(blog__userinfo__username=username)
    # print(article_data_obj)
    article_obj = Article.objects.get(pk=pk)
    comment_data_all = Comment.objects.filter(article=article_obj)
    # print(article_obj)
    return render(request, 'article_detail.html', locals())


# 点赞点踩视图函数
def up_down(request, *args, **kwargs):
    # 先校验当前用户是否登录，如果没有登陆则让其先登录
    if not request.user.is_authenticated:
        return CommonReponse(code=2001, errors=mark_safe("请先<a href='/user/login/'>登录</a> 后再发表评论!"))
    # 处理点赞或者点踩的逻辑
    data = request.POST
    article_id = data.get("article_id")
    up_or_down = json.loads(data.get("up_or_down"))  # 字符串形式的 false / true

    # 获取到当前用户对象和文章对象
    user_obj = request.user
    article_obj = Article.objects.get(pk=int(article_id))

    # 校验当前用户是否是文章的作者，如果是当前文章的作者则不允许给自己点赞或点踩
    if user_obj.username == article_obj.blog.userinfo.username:
        return CommonReponse(code=2005, errors=f"不能给自己点赞或点踩!")

    # 调用点赞或者点踩表进行点赞或者点踩数据的写入
    # 【1】先确认当前用户是否给当前文章点赞或者点踩过
    try:
        # 使用get方法获取用户对象的时候不存在会报错
        up_down_obj = UpAndDown.objects.get(user=user_obj, article=article_obj)
    # 【2】如果当前用户没有给当前文章点赞或点踩过则新增点赞点踩信息
    except Exception:
        UpAndDown.objects.create(user=user_obj, article=article_obj, up_or_down=up_or_down)
        if up_or_down:
            article_obj.up_num += 1
            article_obj.save()
            return CommonReponse(code=2000, message="点赞成功!")
        else:
            article_obj.down_num += 1
            article_obj.save()
            return CommonReponse(code=2000, message="点踩成功!")

    # 【3】如果已经存在点赞点踩记录
    # （1）如果当前是点赞的状态并且发送的数据页是点赞
    if up_down_obj.up_or_down and up_or_down:
        return CommonReponse(code=2002, errors="当前用户已经点赞过了!")
    # （3）当前状态是点踩并且发送的也是点踩
    elif not up_down_obj.up_or_down and not up_or_down:
        return CommonReponse(code=2002, errors="当前用户已经点踩过了!")
    # （2）如果当前是点赞的状态并且发送的数据页是点踩
    elif up_down_obj.up_or_down and not up_or_down:
        # 将当前点赞的信息重置为点踩
        up_down_obj.up_or_down = up_or_down
        article_obj.up_num -= 1
        article_obj.down_num += 1
        up_down_obj.save()
        article_obj.save()
        return CommonReponse(code=2000, message=f"当前点踩成功，感谢指教!")
    else:
        # 将当前点赞的信息重置为点赞
        up_down_obj.up_or_down = up_or_down
        article_obj.up_num += 1
        article_obj.down_num -= 1
        up_down_obj.save()
        article_obj.save()
        return CommonReponse(code=2000, message=f"当前点赞成功，感谢支持!")


@login_required
# 评论视图函数
def comment(request, *args, **kwargs):
    if request.method == "POST" and request.is_ajax():
        data = request.POST
        article_id = data.get('article_id')
        content = data.get('content')
        Comment.objects.create(user=request.user, article_id=int(article_id), content=content)
        return CommonReponse(code=2000, message="评论成功")


class ArticleAdd(View):
    def get(self, request, *args, **kwargs):
        # article_obj_all = Article.objects.filter(blog=request.user.blog)
        category_obj_all = CategoryClass.objects.filter(blog=request.user.blog)
        tag_obj_all = CategoryTag.objects.filter(blog=request.user.blog)

        return render(request, 'add_article.html', locals())

    def post(self, request, *args, **kwargs):
        data = request.POST
        article_title = data.get('article_title')
        article_content = data.get('article_content')
        article_class = data.get('article_class')
        print(article_class)
        article_tag = data.getlist('article_tag')
        print(article_tag)
        # 创建 BS4对象
        soup = BeautifulSoup(article_content, 'lxml')
        desc = soup.text[:50]
        # 获取所有标签
        tags = soup.find_all()
        # 删除指定标签
        for tag in tags:
            if tag.name == "script":
                tag.decompose()
        article_content = str(soup)
        self.__save_data(
            request=request,
            article_title=article_title,
            desc=desc,
            article_content=article_content,
            article_class=article_class,
            article_tag=article_tag
        )
        return redirect('/backend/backend/')

    def __save_data(self, request, article_title, desc, article_content, article_class, article_tag):
        article_obj = Article.objects.create(title=article_title, desc=desc, content=article_content,
                                             blog=request.user.blog,
                                             category=article_class)
        for article_tag_id in article_tag:
            tag_obj = CategoryTag.objects.get(id=article_tag_id)
            ArticleToTag.objects.create(article=article_obj, tag=tag_obj)

def article_upload_img(request):
    article_img_obj=request.FILES.get("imgFile")
    # 存放的位置
    img_dir_path=os.path.join(settings.BASE_DIR,'media/article_img')
    # 保证文件路径存在
    os.makedirs(img_dir_path,exist_ok=True)
    img_path=os.path.join(img_dir_path,article_img_obj.name)
    with open(img_path,'wb') as f:
        # Django自带的数据流写入
        for data in article_img_obj.chunks():
            f.write(data)
    '''
     //成功时
     {
             "error" : 0,
             "url" : "http://www.example.com/path/to/file.ext"
     }
     //失败时
     {
             "error" : 1,
             "message" : "错误信息"
     }
     '''
    return CommonReponse(error=0,url=f'/media/article_img/{article_img_obj.name}')

